package zheezes.eisp.monitor.model;

import java.sql.SQLException;
import java.util.List;

import org.apache.log4j.PropertyConfigurator;

import zheezes.eisp.data.orm.Concentrator;
import zheezes.eisp.data.orm.GroupPo;
import zheezes.eisp.util.SpringUtil;
import zheezes.model.ObservableTreeNode;
import zheezes.util.Visitor;


import com.ibatis.sqlmap.client.SqlMapClient;

public class TreeFactory {
	private SqlMapClient sqlMapper;

	private ObservableTreeNode findNodeById(ObservableTreeNode tree, Integer id) {
		Object data = tree.getData();
		if (data != null) {
			if (data instanceof GroupPo) {
				GroupPo group = (GroupPo) data;
				if (group.getId().intValue() == id) {
					return tree;
				}
			}
		}
		if (tree.hasChildren()) {
			for (Object o : tree.getChildren()) {
				ObservableTreeNode node = (ObservableTreeNode) o;
				ObservableTreeNode r = findNodeById(node, id);
				if (r != null) {
					return r;
				}
			}
		}
		return null;
	}

	public ObservableTreeNode createGroupTree() {
		ObservableTreeNode tree = new ObservableTreeNode();
		List list = null;
		try {
			list = sqlMapper.queryForList("queryAllGroup");
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
		while (list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				GroupPo group = (GroupPo) list.get(i);
				Integer pid = null;
				GroupTreeNode node = new GroupTreeNode();
				node.setData(group);
				ObservableTreeNode parent = null;
				if ((pid = group.getParent()) == null) {
					parent = tree;
				} else {
					parent = findNodeById(tree, pid);
				}

				if (parent != null) {
					parent.addChild(node);
					list.remove(i);
					i--;
				}
			}
		}
		return tree;
	}

	public ObservableTreeNode createTree() {
		ObservableTreeNode tree = createGroupTree();
		if (tree != null) {
			List list = null;
			try {
				list = sqlMapper.queryForList("queryAllCon");
			} catch (SQLException e) {
				e.printStackTrace();
				return tree; // just no concentrator
			}
			for (Object o : list) {
				Concentrator con = (Concentrator) o;
				ConTreeNode node = new ConTreeNode();
				node.setData(con);
				ObservableTreeNode parent = null;
				Integer pid = con.getGid();
				// this is illogical, shall lvc can be first level child? but in db, it is
				if(pid == null) {
					parent = tree;
				} else {
					parent = findNodeById(tree, pid);
				}
				if (parent != null) {
					parent.addChild(node);
				}
			}
		}
		return tree;
	}
	
	public List<ObservableTreeNode> create() {
		return createTree().getChildren();
	}

	public static void main(String[] args) {
		PropertyConfigurator.configure("log4j.properties");
		TreeFactory builer = (TreeFactory) SpringUtil.getApplicationContext()
				.getBean("treeFactory");
		ObservableTreeNode<GroupPo> root = builer.createTree();
		root.traverse(new Printer());
	}

	public void setSqlMapper(SqlMapClient sqlMapper) {
		this.sqlMapper = sqlMapper;
	}
}

class Printer implements Visitor {
	public void visit(Object o) {
		if (o != null) {
			if (o instanceof GroupPo) {
				GroupPo group = (GroupPo) o;
				System.out.println(group.getName());
			} else if (o instanceof Concentrator) {
				Concentrator con = (Concentrator) o;
				System.out.println(con.getLogicAddr());
			}
		}
	}
}
